﻿using Back_end.APIModels;
using Back_end.Models;
using System;
using System.Data;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Web.Http;
using System.Web.Http.Cors;
using System.Web.Http.Description;

namespace Back_end.APIControllers
{
    /// <summary>
    /// 举报API
    /// </summary>
    [Authorize]
	[EnableCors("*", "*", "*")]
	[RoutePrefix("api/Complaints")]
    public class ComplaintsApiController : ApiController
    {
        private ApplicationDbContext db = new ApplicationDbContext();

		/// <summary>
		/// 获取所有举报
		/// </summary>
		/// <returns>所有举报的完整信息</returns>
        // GET: /api/Complaints
		[AllowAnonymous]
		[Route("GetAll")]
        public IQueryable<Complaint> GetComplaints()
        {
			return db.Complaints.OrderBy(c => c.Weight);
        }

		/// <summary>
		/// 获取指定用户发布的举报
		/// </summary>
		/// <param name="id">用户Id</param>
		/// <returns>该用户的所有举报的完整信息</returns>
		// GET: /api/Complaints/5
		[AllowAnonymous]
		[ResponseType(typeof(Complaint))]
		[Route("GetById")]
        public IHttpActionResult GetComplaint(string id)
        {
            Complaint complaint = db.Complaints.Find(id);
            if (complaint == null)
            {
                return NotFound();
            }

            return Ok(complaint);
        }

		/// <summary>
		/// 按用户名获取举报
		/// </summary>
		/// <param name="userName">用户名</param>
		/// <returns>该用户的所有举报的完整信息</returns>
		[AllowAnonymous]
		[ResponseType(typeof(Complaint))]
		[Route("GetByName")]
		public IHttpActionResult GetComplaintByName(string userName)
		{
			if (userName == null)
				return BadRequest();
			var user = db.Users.Where(u => u.UserName == userName).FirstOrDefault();
			if (user == null)
				return NotFound();
		
			return Ok(user.Complaints.OrderBy(c => c.PublishedDate));
		}

		[AllowAnonymous]
		[ResponseType(typeof(Complaint))]
		[Route("Search")]
		public IHttpActionResult GetComplaintByContext(string context)
		{
			var list = from c in db.Complaints
					   where c.Text.Contains(context)
					   select c;

			if (list == null || list.Count() == 0)
				return NotFound();

			return Ok(list);
		}

		/// <summary>
		/// 发布新举报
		/// </summary>
		/// <param name="complaint">要发布的举报</param>
		/// <returns>发布是否成功</returns>
		// POST: /api/Complaints/post
		// [AllowAnonymous]
		[ResponseType(typeof(Complaint))]
		[Route("Post")]
        public IHttpActionResult PostComplaint(ComplaintBindingModel complaintBinding)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

			var submitUser = db.Users.Where(u => u.UserName == complaintBinding.UserName).FirstOrDefault();
			if (submitUser == null)
				return NotFound();
			if (!submitUser.HadAuthentication)
				return BadRequest("未实名认证");

			var now = DateTime.Now;
			if (submitUser.TodayCount++ >= 10086)
			{
				if (submitUser.LastestDate.Value.Date < now.Date)
					submitUser.TodayCount = 0;
				else
					return BadRequest();
			}

			if (complaintBinding.Company != "" && complaintBinding.Company != "无")
			{
				var dbCompany = db.Companies.Find(complaintBinding.Company);
				if (dbCompany != null)
					return NotFound();
				else
					dbCompany.ComplaintCount += 1;
			}

			var complaint = new Complaint
			{
				UserName = complaintBinding.UserName,
				Text = complaintBinding.Text,
				PicturePath = complaintBinding.PicturePath,
				Company = complaintBinding.Company,
				Location = complaintBinding.Location,
				Tag = complaintBinding.Tag,
				Coordinate = complaintBinding.Coordinate,
				ComplaintId = complaintBinding.UserName + now.ToString("yyyyMMddHHmmss"),
                Weight = 1
			};

			db.FollowedList.Add(new FollowedUser
			{
				ComplaintId = complaint.ComplaintId,
				UserName = submitUser.UserName
			});

			submitUser.LastestDate = complaint.PublishedDate = now;
			submitUser.Complaints.Add(complaint);

			db.Complaints.Add(complaint);
            try
            {
                db.SaveChanges();
            }
            catch (DbUpdateException)
            {
                if (ComplaintExists(complaint.ComplaintId))
                    return Conflict();
                else
                    throw;
            }

			return Ok();
        }

		/// <summary>
		/// 关注问题
		/// </summary>
		/// <param name="userId">关注者Id</param>
		/// <param name="complaintId">被关注举报Id</param>
		/// <returns>关注是否成功</returns>
		// [ResponseType(typeof(Complaint))]
		[Route("Followed")]
		public IHttpActionResult Followed(UserComplaintBindingModel followed)
		{
			if (!ModelState.IsValid)
				return BadRequest();

			var user = db.Users.Where(u => u.UserName == followed.UserName).FirstOrDefault();
			var complaint = db.Complaints.Find(followed.ComplaintId);
			if (user == null || complaint == null)
				return NotFound();

			var fl = from f in db.FollowedList
					 where f.ComplaintId == complaint.ComplaintId
						&& f.UserName == user.UserName
					 select f;

			if (fl.Count() > 0)
				return BadRequest("请勿重复关注");

			db.FollowedList.Add(new FollowedUser
			{
				UserName = user.UserName,
				ComplaintId = complaint.ComplaintId
			});
			complaint.Weight += 1;

			db.SaveChanges();

			return Ok(complaint);
		}

		// [ResponseType(typeof(Complaint))]
		[Route("UnFollowed")]
		public IHttpActionResult UnFollowed(UserComplaintBindingModel followed)
		{
			if (!ModelState.IsValid)
				return BadRequest();

			var user = db.Users.Where(u => u.UserName == followed.UserName).FirstOrDefault();
			var complaint = db.Complaints.Find(followed.ComplaintId);
			if (user == null || complaint == null)
				return NotFound();

			var fl = from f in db.FollowedList
					 where f.ComplaintId == complaint.ComplaintId
						&& f.UserName == user.UserName
					 select f;

			if (fl.Count() == 0)
				return BadRequest("还未关注");

			db.FollowedList.Remove(fl.First());
			complaint.Weight -= 1;

			db.SaveChanges();

			return Ok(complaint);
		}

		// [ResponseType(typeof(Complaint))]
		[Route("Liked")]
		public IHttpActionResult Liked(UserComplaintBindingModel followed)
		{
			if (!ModelState.IsValid)
				return BadRequest();

			var user = db.Users.Where(u => u.UserName == followed.UserName).FirstOrDefault();
			var complaint = db.Complaints.Find(followed.ComplaintId);
			if (user == null || complaint == null)
				return NotFound();

			var ll = from l in db.Likes
					 where l.ComplaintId == complaint.ComplaintId 
						&& l.UserName == user.UserName
					 select l;

			if (ll.Count() > 0)
				return BadRequest("请勿重复赞");

			db.Likes.Add(new LikedUser
			{
				UserName = user.UserName,
				ComplaintId = complaint.ComplaintId
			});
			complaint.Weight += 2;

			db.SaveChanges();

			return Ok(complaint);
		}

		// [ResponseType(typeof(Complaint))]
		[Route("UnLiked")]
		public IHttpActionResult UnLiked(UserComplaintBindingModel followed)
		{
			if (!ModelState.IsValid)
				return BadRequest();

			var user = db.Users.Where(u => u.UserName == followed.UserName).FirstOrDefault();
			var complaint = db.Complaints.Find(followed.ComplaintId);
			if (user == null || complaint == null)
				return NotFound();

			var ll = from l in db.Likes
					 where l.ComplaintId == complaint.ComplaintId
						&& l.UserName == user.UserName
					 select l;

			if (ll.Count() == 0)
				return BadRequest("还未赞过");

			db.Likes.Remove(ll.First());
			complaint.Weight -= 2;

			db.SaveChanges();

			return Ok(complaint);
		}

		[AllowAnonymous]
		[HttpGet]
		[Route("FollowedList")]
		public IHttpActionResult GetFollowedUsers(string complaintId)
		{
			var nameList = from f in db.FollowedList
						   where f.ComplaintId == complaintId
						   select f.UserName;

			return Ok(nameList);
		}

		[AllowAnonymous]
		[HttpGet]
		[Route("LikedList")]
		public IHttpActionResult GetLikedUsers(string complaintId)
		{
			var nameList = from f in db.Likes
						   where f.ComplaintId == complaintId
						   select f.UserName;

			return Ok(nameList);
		}

		protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }

        private bool ComplaintExists(string id)
        {
            return db.Complaints.Count(e => e.ComplaintId == id) > 0;
        }
    }
}